﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Messaging;
using A2DFramework.QueueService.Providers.MessageFormatters;

namespace A2DFramework.QueueService.Providers.MSMQ
{
    class MSMQProvider:IQueueProvider
    {   
        public bool IsQueueExists(string queueName)
        {
            string qStr = string.Format(QueueConfiguration.QueueConfiguration.MSMQSettings.QueueFormat, queueName);
            return MessageQueue.Exists(qStr);
        }

        public void CreateQueue(string queueName)
        {
            string qStr = string.Format(QueueConfiguration.QueueConfiguration.MSMQSettings.QueueFormat, queueName);
            MessageQueue.Create(qStr, true);
        }

        public void DeleteQueue(string queueName)
        {
            string qStr = string.Format(QueueConfiguration.QueueConfiguration.MSMQSettings.QueueFormat, queueName);
            MessageQueue.Delete(qStr);
        }

        public void SendMessage(string queueName, InnerMessageWrapper message)
        {
            string qStr = string.Format(QueueConfiguration.QueueConfiguration.MSMQSettings.QueueFormat, queueName);

            MessageQueue mq = new MessageQueue(qStr);
            MessageQueueTransaction tx = new MessageQueueTransaction();

            Message msg = new Message();
            msg.Body = message;
            msg.Formatter = new ProtobufMessageFormater(message.GetType());
            if(!string.IsNullOrEmpty(message.CorrelationID))
                msg.CorrelationId = message.CorrelationID;

            tx.Begin();
            mq.Send(msg, tx);
            tx.Commit();

            mq.Close();

            message.MessageID = msg.Id;
        }

        public InnerMessageWrapper ReceiveMessage(string queueName, string relatedMsgId="")
        {
            string qStr = string.Format(QueueConfiguration.QueueConfiguration.MSMQSettings.QueueFormat, queueName);

            using (MessageQueue mq = new MessageQueue(qStr))
            {
                mq.Formatter = new ProtobufMessageFormater(typeof(InnerMessageWrapper));

                Message msg =null;
                if (string.IsNullOrEmpty(relatedMsgId))
                    msg = mq.Receive();
                else
                    msg = mq.ReceiveByCorrelationId(relatedMsgId, TimeSpan.FromDays(1));

                InnerMessageWrapper receivedMsg = (InnerMessageWrapper)msg.Body;
                receivedMsg.MessageID = msg.Id;
                return receivedMsg;
            }
        }
    }
}
